// Copyright (c) 2000 Just Objects B.V. <just@justobjects.nl>
// Distributable under LGPL license. See terms of license at gnu.org.

package nl.justobjects.pushlet.test;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

/** 
 * Handle a multipart HTTP response using multipart MIME.
 *
 * <p><h4>Usage</h4>
 * <pre>
 * public class MultipartHttpResponseTester extends HttpServlet {
 *     
 *   public void doGet(HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException {
 *     try {
 *       MultipartHttpResponse multipartRsp=new MultipartHttpResponse(req, rsp);
 *       int maxPages=3;
 *       for (int i=1; i <= maxPages+1; i++) {
 *   	    multipartRsp.beginPart();
 *          multipartRsp.out.print(Multipart: page "+i+" of "+maxPages);
 *          multipartRsp.endPart(i==maxPages);
 *          Thread.sleep(3000);
 *       }
 *     } catch (Exception ioe) {
 *       rsp.getWriter().write("Multipart- exception: "+ioe);
 *     }
 *   }
 *
 * </pre>
 *
 * @version $Id: MultipartHttpResponse.java,v 1.4 2003/08/15 08:37:41 justb Exp $
 * @author Just van den Broecke - Just Objects &copy;
 * @see MultipartHttpResponseTest
 */
public class MultipartHttpResponse {
	private String boundary = "End.";
	private static final String CRLF = "\015\012";
	private static final String multipartMimeType = "multipart/x-mixed-replace";
	   
    /** PrintWriter to write output content. */
    public ServletOutputStream out = null; 

    /** MultiPartResponse constructor. */
    public MultipartHttpResponse(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
		
		if (!agentCanHandleMultipart(req)) {
		     throw new IOException("MultiPart MIME not supported by browser (MSIE?)");
		}
		
		// Make boundary unique
		boundary += Long.toString(System.currentTimeMillis(), 36);
			
		rsp.setContentType(multipartMimeType+";boundary="+boundary);
		rsp.setHeader("Expires","1 Jan 1971");
		
		out = rsp.getOutputStream();
		out.print("--"+boundary+CRLF);
		out.flush();
		
		/* SHOULD WE USE CLOSE FOR HTTP1.1 ????  */
		if ("HTTP/1.1".equals(req.getProtocol())) {
			rsp.setHeader("Connection", "close");
		}
    }
 	
	/** Determine if our remote (browser) agent can handle multipart. */
	static public boolean agentCanHandleMultipart(HttpServletRequest req) throws IOException {
		String ua = req.getHeader("User-Agent");
		
		// Fpr now assume only MS Internet Exploder cannot do Multipart
		if (ua != null && ua.indexOf("MSIE") > 0) {
		     return false;
		}
		
		// Assume all others (NS,...) support it
		return true;
	}

	/** Begin a next part containing plain HTML. */
	public void beginPart() throws IOException {
		beginPart("text/html");
	}

   /** Begin a next part with specified MIME content type. */
    public void beginPart(String contentType) throws IOException {
		out.print("Content-type: "+contentType+CRLF+CRLF);
    }
    
	/** End the current part but not the response. */
	public void endPart() throws IOException {
		endPart(false);
	}

	/** End the entire response. */
	public void endResponse() throws IOException {
		endPart(true);
	}

	/** End the current part; optionally ends the response. */
    public void endPart(boolean endRsp) throws IOException {
        out.print(CRLF+"--"+boundary+(endRsp?"--":"")+CRLF);
        out.flush();
    }
}

/*
 * $Log: MultipartHttpResponse.java,v $
 * Revision 1.4  2003/08/15 08:37:41  justb
 * fix/add Copyright+LGPL file headers and footers
 *
 *
 */